package queryid

import (
	"encoding/json"
	"strings"

	"github.com/go-redis/redis"
)

type variableMem map[string]interface{}

const errorCodeBase = 0
const (
	errorCodeNoError = errorCodeBase + iota
	errorCodeBufError
	errorCodeJSONError
	errorCodeHandleError
	errorCodeCusNotFound
)

const (
	errorReasonSuccess     = "success"
	errorReasonCusNotFound = "cus not found"
)

const (
	typeKeyBackIVRQuery     = 95
	typeIVRQueryCalled      = 96
	typeCommonIVRQuery      = 97
	typeQueryCalledWithVOld = 98
	typeQueryCalledOld      = 99
)
const (
	jsonKeyRequest    = "request"
	jsonKeyCallType   = "callType"
	jsonKeyType       = "type"
	jsonKeyIdentiCode = "identiCode"
	jsonKeyVariables  = "variables"
	jsonKeyTel        = "tel"
	jsonKeyCaller     = "caller"

	jsonKeyUserQueryID = "usrQueryId"
	jsonKeyInputKeys   = "inputKeys"
)
const (
	redisMemberCus = "cusInfo"
)

const (
	cusHashPrefix = "tel"
)

type commonQueryCusIDNotFoundRsp struct {
	Retcode     int           `json:"retcode"`
	Reason      string        `json:"reason"`
	UserQueryID string        `json:"userQueryId"`
	Variables   []variableMem `json:"variables"`
}
type commonQueryCusIDNotFoundStru struct {
	Response commonQueryCusIDRsp `json:"response"`
}

func genRedisCusKey(tel string) string {
	return strings.Join([]string{cusHashPrefix, tel}, "-")
}

//getIdentiCodeByTelNumber, if find return code nil, if not find return nil, nil.
func (p *ReqPriD) getIdentiCodeByTelNumber(tel string) (code string, err error) {
	key := genRedisCusKey(tel)
	code, err = p.Rdb.HGet(redisMemberCus, key).Result()

	if err != nil {
		if err == redis.Nil {
			p.logf(LOG_INFO, "tel:%s not found", tel)
			return code, nil
		}
	}
	return code, err
}

func (p *ReqPriD) insertIdentiCodeByTelNumber(tel, code string) (err error) {
	key := genRedisCusKey(tel)
	set := p.Rdb.HSet(redisMemberCus, key, code)
	if err := set.Err(); err != nil {
		p.logf(LOG_INFO, "insert tel:%s error", tel)
		return err
	}
	return err
}

//GenErrorResp we should change error to finish
func (p *ReqPriD) GenErrorResp() (rsp []byte, err error) {
	errData := commonQueryFinshedStru{
		Response: &commonQueryFinshedRsp{
			Retcode: errorCodeNoError,
			Reason:  errorReasonSuccess,
			NextAction: &nextActionFinishNode{
				Action: actionTypeFinish,
			},
		},
	}
	rsp, err = json.Marshal(errData)
	return rsp, nil
}

//GenNotFindResp we should change not found to error
func (p *ReqPriD) GenNotFindResp() (rsp []byte, err error) {
	errData := rspStruct{
		Response: rspStructResponse{
			Retcode: errorCodeCusNotFound,
			Reason:  errorReasonCusNotFound,
		},
	}
	rsp, err = json.Marshal(errData)
	return rsp, nil
}

//GenReturnCodeForVoicePlay the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnCodeForVoicePlay(code string) (rsp []byte, err error) {
	var rspData commonQueryCusIDStru

	vari := make(variableMem)
	vari[jsonKeyIdentiCode] = code
	rspData.Response = &commonQueryCusIDRsp{}
	rspData.Response.Variables = append(rspData.Response.Variables, vari)
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &nextActionPlayVoiceNode{}
	rspData.Response.NextAction.Action = actionTypePlayVoice
	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnCodeForVoicePlayTest1 the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnCodeForVoicePlayTest1(code string) (rsp []byte, err error) {
	var rspData commonQueryCusIDStru

	vari := make(variableMem)
	vari[jsonKeyIdentiCode] = code
	rspData.Response = &commonQueryCusIDRsp{}
	rspData.Response.Variables = append(rspData.Response.Variables, vari)
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &nextActionPlayVoiceNode{}
	rspData.Response.NextAction.Action = actionTypePlayVoice
	rspData.Response.NextAction.Params = &nextActionPlayVoiceParams{}
	rspData.Response.NextAction.Params.VoiceTempName = "播报id语音1"
	rspData.Response.NextAction.Params.AllowBreak = 1
	rspData.Response.NextAction.Params.VoiceTempParams = code

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenKeyBackTest1
func (p *ReqPriD) GenKeyBackTest1() (rsp []byte, err error) {
	var rspData keyBackStru
	rspData.Response = &keyBackRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.VirtualKey = "3"

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnCodeForAction1 the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnCodeForAction1() (rsp []byte, err error) {
	var rspData commonQueryCusIDStru

	rspData.Response = &commonQueryCusIDRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &nextActionPlayVoiceNode{}
	rspData.Response.NextAction.Action = actionTypePlayVoice
	rspData.Response.NextAction.Params = &nextActionPlayVoiceParams{}
	rspData.Response.NextAction.Params.VoiceTempName = "播报id语音1"
	rspData.Response.NextAction.Params.AllowBreak = 1
	rspData.Response.NextAction.Params.VoiceTempParams = "111"

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnForGroup the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnForGroup() (rsp []byte, err error) {
	var rspData commonIVRStru

	rspData.Response = &commonIVRRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &commonActionNode{}
	rspData.Response.NextAction.Action = actionTypeToGroup
	actionParam := nextActionToGroupParams{
		AcdName:     "交互式转技能组1",
		SwitchTimes: 2,
		RingTimeout: 5,
		QueueTime:   5,
	}
	rspData.Response.NextAction.Params = &actionParam

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnForSeat the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnForSeat() (rsp []byte, err error) {
	var rspData commonIVRStru

	rspData.Response = &commonIVRRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &commonActionNode{}
	rspData.Response.NextAction.Action = actionTypeToSeat
	actionParam := nextActionToSeatParams{
		WorkNumber:  "hlwqds1",
		Number:      "1916",
		RingTimeout: 5,
		//QueueTime: 5,
	}
	rspData.Response.NextAction.Params = &actionParam

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnForOutlineNumber the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnForOutlineNumber() (rsp []byte, err error) {
	var rspData commonIVRStru

	rspData.Response = &commonIVRRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &commonActionNode{}
	rspData.Response.NextAction.Action = actionTypeToOutlineNumber
	actionParam := nextActionToOutlineNumber{
		Called:    "02557926532",
		OutNumber: "02566687671",
	}
	rspData.Response.NextAction.Params = &actionParam

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnForIVRFlow the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnForIVRFlow() (rsp []byte, err error) {
	var rspData commonIVRStru

	rspData.Response = &commonIVRRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &commonActionNode{}
	rspData.Response.NextAction.Action = actionTypeToIVRFlow
	actionParam := nextActionToIVRFlow{
		IvrFlowName: "通用查询技能组",
	}
	rspData.Response.NextAction.Params = &actionParam

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnForEnd the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnForEnd() (rsp []byte, err error) {
	var rspData commonIVRStru

	rspData.Response = &commonIVRRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &commonActionNode{}
	rspData.Response.NextAction.Action = actionTypeFinish

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnForPlayVoice2 the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnForPlayVoice2() (rsp []byte, err error) {
	var rspData commonIVRStru

	rspData.Response = &commonIVRRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &commonActionNode{}
	rspData.Response.NextAction.Action = actionTypePlayVoice
	actionParam := nextActionToVoice2Params{
		VoiceName:      "欢迎欢迎热烈欢迎",
		AllowBreak:     1,
		GetKeyNumber:   5,
		GetKeyTimeout:  10,
		EndWithHashKey: 1,
	}
	rspData.Response.NextAction.Params = &actionParam

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}

//GenReturnCodeForAction2 the server ask us the cus's tel to play, we should answer
func (p *ReqPriD) GenReturnCodeForAction2() (rsp []byte, err error) {
	var rspData commonPlayVoiceDigStru

	rspData.Response = &commonPlayVoiceDigRsp{}
	rspData.Response.Retcode = errorCodeNoError
	rspData.Response.Reason = errorReasonSuccess
	rspData.Response.NextAction = &nextActionPlayVoiceDigNode{}
	rspData.Response.NextAction.Action = actionTypePlayVoice
	rspData.Response.NextAction.Params = &nextActionPlayVoiceDigParams{}
	rspData.Response.NextAction.Params.VoiceTempName = "播报id语音1"
	rspData.Response.NextAction.Params.AllowBreak = 1
	rspData.Response.NextAction.Params.VoiceTempParams = "111"

	rsp, err = json.Marshal(rspData)

	return rsp, nil
}
